home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <malloc.h>
- #include "TimeEntry.h"
- #include "TimeGrid.h"
- #include "TimeInterval.h"
-
- #include <Xm/Frame.h>
- #include <Xm/LabelG.h>
- #include <Xm/Text.h>
-
- static int count;
- static Arg args[10];
- static Boolean deleted;
- static TimeEntry *deletedObject;
-
- char *
- xs_get_string_from_xmstring (XmString string)
- {
- XmStringContext context;
- char *text;
- XmStringCharSet charset;
- XmStringDirection dir;
- Boolean separator;
- char *buf = NULL;
-
- int done = FALSE;
- XmStringInitContext (&context, string);
- while (!done)
- if(XmStringGetNextSegment (context, &text, &charset,
- &dir, &separator)){
- if(buf){
- buf = XtRealloc(buf, strlen(buf) + strlen(text) + 2);
- strcat(buf, text);
- }
- else {
- buf = (char *) XtMalloc(strlen(text) +1);
- strcpy(buf, text);
- }
- XtFree(text);
- if(buf && separator) {
- buf = XtRealloc(buf, strlen(buf) + 2);
- strcat(buf, "\n");
- }
- }
- else
- done = TRUE;
-
- XmStringFreeContext (context);
- if (buf && buf[strlen(buf)-1] == '\n') {
- buf[strlen(buf)-1] = '\0';
- }
- return buf;
- }
-
-
- TimeEntry::TimeEntry(const char *n, TimeGrid *grid)
- : VkComponent(n)
- {
- _grid = grid;
-
- _callback = NULL;
-
- TimeEntry::build();
- }
-
- TimeEntry::~TimeEntry()
- {
- if (::deletedObject == this) {
- ::deleted = True;
- }
- if (_baseWidget) {
- XtRemoveEventHandler(_baseWidget, ButtonPressMask, False,
- TimeEntry::button_press, (XtPointer) this);
- }
- if (_grid->getText() &&
- _grid->getText()->getCallbackData() == (XtPointer) this) {
- _grid->getText()->setCallback(NULL, NULL);
- _grid->getText()->hide();
- }
- }
-
- /**********************************************************************/
-
- const char *
- TimeEntry::className()
- {
- return "TimeEntry";
- }
-
- void
- TimeEntry::raise()
- {
- if (XtWindow(_baseWidget)) {
- XRaiseWindow(XtDisplay(_baseWidget), XtWindow(_baseWidget));
- }
- }
-
- void
- TimeEntry::setCallback(XtCallbackProc proc, XtPointer client_data)
- {
- _callback = proc;
- _callbackData = client_data;
- }
-
- Boolean
- TimeEntry::setTimeInterval(int s, int l)
- {
- _start = s;
- _length = l;
- if (_baseWidget) {
- return reposition();
- } else {
- return True;
- }
- }
-
- char *
- TimeEntry::getText()
- {
- XmString xs;
- char *result;
-
- count = 0;
- XtSetArg(args[count], XmNlabelString, &xs); count++;
- XtGetValues(_label, args, count);
- if (result = xs_get_string_from_xmstring(xs)) {
- return result;
- } else {
- return strdup("");
- }
- /*
- if (XmStringGetLtoR(xs, XmSTRING_DEFAULT_CHARSET, &result)) {
- return result;
- } else {
- return strdup("");
- }
- */
- }
-
- void
- TimeEntry::setText(char *str)
- {
- XmString xs;
-
- xs = XmStringCreateLtoR(str, XmFONTLIST_DEFAULT_TAG);
- count = 0;
- XtSetArg(args[count], XmNlabelString, xs); count++;
- XtSetValues(_label, args, count);
- XmStringFree(xs);
- }
-
- Boolean
- TimeEntry::reposition()
- {
- Position x, y;
- Dimension width, height;
-
- if (_grid->requestPosition(_start, _length, &x, &y, &width, &height)) {
- count = 0;
- XtSetArg(args[count], XmNx, x); count++;
- XtSetArg(args[count], XmNy, y); count++;
- XtSetArg(args[count], XmNwidth, width); count++;
- XtSetArg(args[count], XmNheight, height); count++;
- XtSetValues(_baseWidget, args, count);
- return True;
- } else {
- return False;
- }
- }
-
- void
- TimeEntry::callCallback(TimeEntryReason reason, XEvent *event)
- {
- TimeEntryCallback data;
-
- if (_callback) {
- data.obj = this;
- data.reason = reason;
- data.event = event;
- (*_callback)(_baseWidget, _callbackData, (XtPointer) &data);
- }
- }
-
- void
- TimeEntry::select(Boolean makeModified)
- {
- raise();
- callCallback(TE_selected);
- layerText(makeModified);
- }
-
- /**********************************************************************/
-
- void
- TimeEntry::build()
- {
- Pixel topShadow, bottomShadow, bg, fg;
- Dimension shadowThickness;
-
- if (_grid->getText()) {
- count = 0;
- XtSetArg(args[count], XmNbackground, &bg); count++;
- XtSetArg(args[count], XmNforeground, &fg); count++;
- XtSetArg(args[count], XmNtopShadowColor, &topShadow); count++;
- XtSetArg(args[count], XmNbottomShadowColor, &bottomShadow); count++;
- XtSetArg(args[count], XmNshadowThickness, &shadowThickness); count++;
- XtGetValues(_grid->getText()->baseWidget(), args, count);
- }
-
- count = 0;
- XtSetArg(args[count], XmNshadowType, XmSHADOW_ETCHED_IN);
- XtSetArg(args[count], XmNhighlightThickness, 0); count++;
- if (_grid->getText()) {
- XtSetArg(args[count], XmNbackground, bg); count++;
- XtSetArg(args[count], XmNforeground, fg); count++;
- XtSetArg(args[count], XmNtopShadowColor, topShadow); count++;
- XtSetArg(args[count], XmNbottomShadowColor, bottomShadow); count++;
- XtSetArg(args[count], XmNshadowThickness, shadowThickness); count++;
- }
- _baseWidget = XmCreateFrame(_grid->getParent(), _name, args, count);
-
- count = 0;
- XtSetArg(args[count], XmNrecomputeSize, False); count++;
- XtSetArg(args[count], XmNalignment, XmALIGNMENT_BEGINNING); count++;
- XtSetArg(args[count], XmNfontList, _grid->getTextFontList()); count++;
- _label = XmCreateLabelGadget(_baseWidget, "timeEntryLabel", args, count);
- XtManageChild(_label);
-
- XtAddEventHandler(_baseWidget, ButtonPressMask, False,
- TimeEntry::button_press, (XtPointer) this);
- installDestroyHandler();
- }
-
- void
- TimeEntry::destroy()
- {
- XtRemoveEventHandler(_baseWidget, ButtonPressMask, False,
- TimeEntry::button_press, (XtPointer) this);
- XtDestroyWidget(_baseWidget);
- }
-
- void
- TimeEntry::menu(XEvent *event)
- {
- callCallback(TE_postMenu, event);
- }
-
- void
- TimeEntry::layerText(Boolean makeModified)
- {
- char *str;
-
-
- // There is the possibility that we will be deleted by resetting of the
- // grid, if we're the entry for the grid text entry and we don't have
- // a string. I should really be able to figure out how to detect the
- // situation before calling TimeGrid::reset and behave differently,
- // but I can't do it right now.
- ::deletedObject = this;
- ::deleted = False;
- _grid->reset();
- if (::deleted) {
- return;
- }
-
- str = getText();
- _grid->getText()->setText(str);
- XtFree(str);
- if (_grid->getText()->setTimeInterval(_start, _length)) {
- _grid->getText()->show();
- _grid->getText()->raise();
- }
- _grid->getText()->setCallback(TimeEntry::text_stub, (XtPointer) this);
- _grid->getText()->setModified(makeModified);
- }
-
- /**********************************************************************/
-
- void
- TimeEntry::button_press(Widget, XtPointer client_data, XEvent *event,
- Boolean *)
- {
- TimeEntry *obj = (TimeEntry *) client_data;
-
- if (event->xbutton.button == Button1) {
- obj->select();
- } else if (event->xbutton.button == Button3) {
- obj->menu(event);
- }
- }
-
- void
- TimeEntry::text_stub(Widget, XtPointer client_data, XtPointer call_data)
- {
- TimeEntry *obj = (TimeEntry *) client_data;
- TimeEntryCallback *cb = (TimeEntryCallback *) call_data;
- char *str;
-
- switch (cb->reason) {
- case TE_textChanged:
- str = obj->_grid->getText()->getText();
- obj->setText(str);
- XtFree(str);
- break;
- case TE_timeChanged:
- obj->setTimeInterval(obj->_grid->getText()->start(),
- obj->_grid->getText()->length());
- break;
- case TE_postMenu:
- case TE_selected:
- case TE_deselect:
- case TE_none:
- break;
- }
- obj->callCallback(cb->reason, cb->event);
- }
-
- /**********************************************************************/
-
- TimeEntryText::TimeEntryText(const char *name, TimeGrid *grid,
- Boolean editable)
- : TimeEntry(name, grid)
- {
- _modified = False;
- _nonEmpty = False;
- _id = NULL;
-
- if (editable) {
- _resizer = new VkResizer();
- _resizer->addCallback(VkResizer::stateChangedCallback, this,
- (VkCallbackMethod) &TimeEntryText::resizeCallback,
- (XtPointer) this);
- } else {
- _resizer = NULL;
- }
-
- TimeEntry::destroy();
- TimeEntryText::build();
- }
-
- TimeEntryText::~TimeEntryText()
- {
- if (_baseWidget) {
- XtRemoveCallback(_baseWidget, XmNactivateCallback,
- TimeEntryText::activate_stub, (XtPointer) this);
- XtRemoveCallback(_baseWidget, XmNmodifyVerifyCallback,
- TimeEntryText::modify_stub, (XtPointer) this);
- XtRemoveCallback(_baseWidget, XmNlosingFocusCallback,
- TimeEntryText::focus_stub, (XtPointer) this);
- XtRemoveCallback(_baseWidget, XmNvalueChangedCallback,
- TimeEntryText::modified_stub, (XtPointer) this);
- XtRemoveEventHandler(_baseWidget, ButtonPressMask, False,
- TimeEntryText::button_press, (XtPointer) this);
- }
- if (_resizer) {
- delete _resizer;
- }
- delete _interval;
- }
-
- /**********************************************************************/
-
- void
- TimeEntryText::hide()
- {
- TimeEntry::hide();
- if (_resizer) {
- _resizer->hide();
- }
- _interval->hide();
- textChanged();
- }
-
- void
- TimeEntryText::raise()
- {
- TimeEntry::raise();
- if (_resizer) {
- _resizer->show();
- }
- _interval->show();
- XmProcessTraversal(_baseWidget, XmTRAVERSE_CURRENT);
- }
-
- /**********************************************************************/
-
- char *
- TimeEntryText::getText()
- {
- char *str;
- int len;
-
- str = XmTextGetString(_baseWidget);
- len = strlen(str);
- if (len == 1 && str[0] == '\n') {
- str[0] = '\0';
- } else if (len > 1 && str[len-1] == '\n' && str[len-2] == '\n') {
- str[len-2] = '\0';
- }
- return str;
- }
-
- void
- TimeEntryText::setText(char *str)
- {
- XmTextSetString(_baseWidget, str);
- _modified = False;
- _nonEmpty = (strlen(str) != 0);
- }
-
- Boolean
- TimeEntryText::reposition()
- {
- Boolean result;
-
- result = TimeEntry::reposition();
- if (result && _resizer) {
- _resizer->setIncrements(0, _grid->getSlotHeight(),
- 0, _grid->getSlotHeight());
- _resizer->adjustGeometry();
- }
- return result;
- }
-
- Boolean
- TimeEntryText::setTimeInterval(int start, int length)
- {
- Boolean result;
-
- result = TimeEntry::setTimeInterval(start, length);
- _interval->setTimeInterval(start, length);
- return result;
- }
-
- /**********************************************************************/
-
- void
- TimeEntryText::build()
- {
- count = 0;
- XtSetArg(args[count], XmNhighlightThickness, 0); count++;
- _baseWidget = XmCreateText(_grid->getParent(), _name, args, count);
- XtAddCallback(_baseWidget, XmNactivateCallback,
- TimeEntryText::activate_stub, (XtPointer) this);
- XtAddCallback(_baseWidget, XmNmodifyVerifyCallback,
- TimeEntryText::modify_stub, (XtPointer) this);
- XtAddCallback(_baseWidget, XmNlosingFocusCallback,
- TimeEntryText::focus_stub, (XtPointer) this);
- XtAddCallback(_baseWidget, XmNvalueChangedCallback,
- TimeEntryText::modified_stub, (XtPointer) this);
- XtAddEventHandler(_baseWidget, ButtonPressMask, False,
- TimeEntryText::button_press, (XtPointer) this);
- if (_resizer) {
- _resizer->attach(_baseWidget);
- _resizer->show();
- }
-
- _interval = new TimeInterval("timeInterval", _grid);
- _interval->setCallback(TimeEntryText::interval_stub, (XtPointer) this);
- }
-
- void
- TimeEntryText::destroy()
- {
- XtRemoveEventHandler(_baseWidget, ButtonPressMask, False,
- TimeEntryText::button_press, (XtPointer) this);
- XtDestroyWidget(_baseWidget);
- }
-
- void
- TimeEntryText::resizeCallback(VkComponent *, XtPointer, XtPointer callData)
- {
- VkResizerReason reason = (VkResizerReason) callData;
-
- switch (reason) {
- case VR_resized:
- case VR_moved:
- updateInterval();
- break;
- case VR_resizing:
- case VR_moving:
- adjustInterval();
- break;
- case VR_none:
- break;
- }
- }
-
- void
- TimeEntryText::updateInterval()
- {
- int oldStart, oldLength;
- Position y;
- Dimension height;
-
- oldStart = _start;
- oldLength = _length;
- count = 0;
- XtSetArg(args[count], XmNy, &y); count++;
- XtSetArg(args[count], XmNheight, &height); count++;
- XtGetValues(_baseWidget, args, count);
- _grid->requestInterval(y, height, &_start, &_length);
- _interval->setTimeInterval(_start, _length);
- if (_start != oldStart || _length != oldLength) {
- callCallback(TE_timeChanged);
- }
- }
-
- void
- TimeEntryText::textChanged()
- {
- if (_modified) {
- callCallback(TE_textChanged);
- }
- _modified = False;
- }
-
- Boolean
- TimeEntryText::textComplete()
- {
- char *str;
- XmTextPosition insert, last;
- Boolean result;
- int len;
-
- result = False;
- insert = XmTextGetInsertionPosition(_baseWidget);
- last = XmTextGetLastPosition(_baseWidget);
- if (insert >= last-1) {
- str = XmTextGetString(_baseWidget);
- len = strlen(str);
- if ((len == 1 && str[0] == '\n') ||
- (len > 1 && str[len-1] == '\n' && str[len-2] == '\n')) {
- result = True;
- }
- XtFree(str);
- }
- return result;
- }
-
- void
- TimeEntryText::doActivate()
- {
- _id = NULL;
- if (textComplete()) {
- textChanged();
- hide();
- callCallback(TE_deselect);
- }
- }
-
- void
- TimeEntryText::scheduleActivate()
- {
- if (!_id) {
- _id = XtAppAddWorkProc(XtWidgetToApplicationContext(_baseWidget),
- TimeEntryText::sched_activate,
- (XtPointer) this);
- }
- }
-
- void
- TimeEntryText::adjustInterval()
- {
- Position x, y;
- Dimension width, height;
- int start, length;
-
- if (_resizer) {
- _resizer->lastLocation(&x, &y, &width, &height);
- }
- _grid->requestInterval(y, height, &start, &length);
- _interval->setTimeInterval(start, length);
- }
-
- /**********************************************************************/
-
- /*
- void
- TimeEntryText::resize_stub(Widget, XtPointer client_data, XtPointer call_data)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
- VkResizerReason reason = (VkResizerReason) call_data;
-
- obj->resizeCallback(reason);
- }
- */
-
- void
- TimeEntryText::activate_stub(Widget, XtPointer client_data, XtPointer)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
-
- obj->scheduleActivate();
- }
-
- void
- TimeEntryText::modify_stub(Widget, XtPointer client_data, XtPointer call_data)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
- XmTextVerifyCallbackStruct *cb = (XmTextVerifyCallbackStruct *) call_data;
-
- if (cb->text->length == 1 && *(cb->text->ptr) == '\n') {
- obj->scheduleActivate();
- }
- }
-
- void
- TimeEntryText::focus_stub(Widget, XtPointer client_data, XtPointer)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
-
- if (obj->_nonEmpty) {
- obj->textChanged();
- }
- }
-
- void
- TimeEntryText::modified_stub(Widget, XtPointer client_data, XtPointer)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
- char *str;
-
- obj->_modified = True;
- str = obj->getText();
- obj->_nonEmpty = (strlen(str) != 0);
- XtFree(str);
- }
-
- void
- TimeEntryText::button_press(Widget, XtPointer client_data, XEvent *event,
- Boolean *)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
-
- if (event->xbutton.button == Button3) {
- obj->menu(event);
- }
- }
-
- Boolean
- TimeEntryText::sched_activate(XtPointer client_data)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
-
- obj->doActivate();
- return True;
- }
-
- void
- TimeEntryText::interval_stub(Widget, XtPointer client_data,
- XtPointer call_data)
- {
- TimeEntryText *obj = (TimeEntryText *) client_data;
- TimeIntervalReason reason = (TimeIntervalReason) call_data;
-
- if (reason == TI_deselect) {
- obj->callCallback(TE_deselect);
- }
- }
-